package com.opslab.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by dobbie on 15-7-5.
 */
public class MD5Util {
    public static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static char hexDigitsLowercase[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'
            , 'v', 'w', 'x', 'y', 'z'};


    /**
     * 对指定字符串进行MD5加密
     *
     * @param s 指定字符串
     * @return MD5加密后的32位16进制
     */
    public final static String MD532Lowercase(String s) throws NoSuchAlgorithmException {
        if (StringUtil.isEmpty(s)) return null;

        try {
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            md5.update(s.getBytes());
            // 获得密文
            byte[] digest = md5.digest();
            //转换成32位
            char chars[] = new char[digest.length * 2];
            int k = 0;
            for (int i = 0; i < digest.length; i++) {
                byte byte0 = digest[i];
                chars[k++] = hexDigitsLowercase[byte0 >>> 4 & 0xf];
                chars[k++] = hexDigitsLowercase[byte0 & 0xf];
            }
            return new String(chars);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }


    }

    /**
     * 对指定字符串进行MD5加密
     *
     * @param s 指定字符串
     * @return MD5加密后的32位16进制
     */
    public final static String MD5(String s) {
        if (StringUtil.isEmpty(s)) return null;
        try {
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            md5.update(s.getBytes());
            // 获得密文
            byte[] digest = md5.digest();
            //转换成32位
            char chars[] = new char[digest.length * 2];
            int k = 0;
            for (int i = 0; i < digest.length; i++) {
                byte byte0 = digest[i];
                chars[k++] = hexDigits[byte0 >>> 4 & 0xf];
                chars[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(chars).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 对指定字符串进行MD5加密
     * 百微盘微信支付指定加密方法
     *
     * @return MD5加密后的32位16进制
     */
    public final static String MD5WX(String text) throws Exception {
        byte[] bytes = text.getBytes("UTF-8");

        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(bytes);
        bytes = messageDigest.digest();

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            if ((bytes[i] & 0xff) < 0x10) {
                sb.append("0");
            }
            sb.append(Long.toString(bytes[i] & 0xff, 16));
        }
        return sb.toString().toLowerCase();
    }

    /*
 * 加密算法
 */
    public static String encode(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(text.getBytes("UTF-8"));
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            String md5 = buf.toString();
            return md5;
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return "";
    }

    public static String md5(String text) throws Exception {
        return md5(text.getBytes("UTF-8"));
    }

    public static String md5(byte[] source) throws Exception {
        int bufferSize = 4096;
        byte[] buffer = new byte[4096];

        MessageDigest md5 = MessageDigest.getInstance("MD5");

        int remain = source.length;

        while (remain > 0) {
            int len = (remain > bufferSize) ? bufferSize : remain;
            System.arraycopy(source, source.length - remain, buffer, 0, len);
            remain = remain - len;

            md5.update(buffer, 0, len);
        }

        return byte2Hex(md5.digest());
    }

    public static String byte2Hex(byte[] bytes) throws Exception {
        final String HEX = "0123456789abcdef";

        String result = "";
        for (int i = 0; i < bytes.length; i++) {
            result += HEX.charAt(bytes[i] >> 4 & 0x0F);
            result += HEX.charAt(bytes[i] & 0x0F);
        }

        return new String(result);
    }

    /**
     * 取文件md5值
     *
     * @param filePath
     * @return
     */
    public static String fileMd5(String filePath) {
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[10240];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {
                md.update(buffer, 0, length);
            }
            BigInteger bigInt = new BigInteger(1, md.digest());

            return String.valueOf(bigInt);
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }

    }

    public static void main(String[] args) {

    }



}
